﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ferhrosa.Wpf;
using MecSom;
using MecSom.Dados;
using System.Timers;

namespace MecSom_Wpf.UserControls
{
    /// <summary>
    /// Interaction logic for TelaServico.xaml
    /// </summary>
    public partial class TelaServico : UserControl
    {

        delegate void MetodoSimples();


        List<Cliente> clientes;

        Timer timerFiltro;

        bool editandoCliente;


        public bool PossuiRegistros
        {
            get
            {
                return this.clientes.Any();
            }
        }

        public TelaPesquisa Pesquisa { get; set; }


        public TelaServico()
        {
            InitializeComponent();

            clientes = new List<Cliente>();

            timerFiltro = new Timer(1000);
            timerFiltro.Enabled = false;
            timerFiltro.AutoReset = false;
            timerFiltro.Elapsed += new ElapsedEventHandler(timerFiltro_Elapsed);

            editandoCliente = false;
        }


        #region Cliente

        /// <summary>
        /// Carrega a lista de clientes do banco de dados.
        /// </summary>
        public void CarregarClientes()
        {
            // Limpa a lista de clientes carregados.
            clientes.Clear();
            // Limpa o filtro aplicado a nome de cliente.
            tbFiltro.Clear();

            // Carrega a lista de clientes do banco de dados, aplicando o filtro selecionado no controle de pesquisa.
            clientes.AddRange(Cliente.Carregar(
                Pesquisa.Numero,
                Pesquisa.Data,
                Pesquisa.Cliente,
                Pesquisa.Telefone,
                Pesquisa.ProcurarContato,
                Pesquisa.Tipo,
                Pesquisa.Marca,
                Pesquisa.Modelo,
                Pesquisa.Situacao
            ));

            // Executa método que aplica o filtro de nome à lista de clientes, o que já os mostra na DataGrid também.
            FiltrarClientes();
        }

        /// <summary>
        /// Filtra lista de clientes pelo nome e já mostra esse resultado na DataGrid.
        /// </summary>
        void FiltrarClientes()
        {
            // Aplica filtro de nome, colocando o resultado na DataGrid.
            var clientesFiltrados = new List<Cliente>(clientes.Where(cliente => cliente.Nome.StartsWith(tbFiltro.Text, StringComparison.InvariantCultureIgnoreCase)));
            dgClientes.ItemsSource = clientesFiltrados;

            // TODO: Verificar se é necessário.
            lblCodCliente.Content = 0;

            if ( dgClientes.Items.Count > 0 && dgClientes.SelectedItem == null ) dgClientes.SelectedIndex = 0;

            AtualizarContadorRegistros();
        }

        private void tbFiltro_TextChanged(object sender, TextChangedEventArgs e)
        {
            // Para e inicia novamente o Timer.
            // Dessa forma sempre que algo for digitado terá que aguardar novamente
            // o tempo do Timer para que o filtro seja executado.
            timerFiltro.Stop();
            timerFiltro.Start();
        }

        void timerFiltro_Elapsed(object sender, ElapsedEventArgs e)
        {
            // Cria instância de delegate referenciando ao método de carregar clientes.
            var carregarClientes = new MetodoSimples(FiltrarClientes);

            // Executa o método de carregar clientes no mesmo thread em que está sendo executada a tela (this.Dispatcher).
            this.Dispatcher.Invoke(carregarClientes, null);
        }

        private void dgClientes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            PreencherCliente();
        }
        void PreencherCliente()
        {
            VerificarNavegacao();

            if ( null != dgClientes.SelectedItem )
            {
                btnRemover.IsEnabled = true;

                var selecionado = (Cliente)dgClientes.SelectedItem;

                lblCodCliente.Content = selecionado.CodCliente;
                tbData.Text = selecionado.DataInclusao.ToShortDateString();
                tbCliente.Text = selecionado.Nome;
                tbTelefone1.Text = selecionado.Telefone1;
                tbTelefone2.Text = selecionado.Telefone2;
                tbTelefone3.Text = selecionado.Telefone3;
                tbContato.Text = selecionado.Contato;
                tbTelefone4.Text = selecionado.Telefone4;
                tbTelefone5.Text = selecionado.Telefone5;
                tbTelefone6.Text = selecionado.Telefone6;

                CarregarServicos();
            }
            else
            {
                btnRemover.IsEnabled = false;
            }

            FinalizarEdicaoCliente();
        }
        void VerificarNavegacao()
        {
            btnPrimeiro.IsEnabled = (dgClientes.SelectedIndex > 0);
            btnAnterior.IsEnabled = (dgClientes.SelectedIndex > 0);
            btnProximo.IsEnabled = (dgClientes.SelectedIndex < (dgClientes.Items.Count - 1));
            btnUltimo.IsEnabled = (dgClientes.SelectedIndex < (dgClientes.Items.Count - 1));

            AtualizarContadorRegistros();
        }

        void AtualizarContadorRegistros()
        {
            lblRegistros.Content = (dgClientes.SelectedIndex + 1).ToString() + " / " + dgClientes.Items.Count.ToString();
        }

        void LimparCliente()
        {
            tbData.Text = String.Empty;
            tbCliente.Text = String.Empty;
            tbTelefone1.Text = String.Empty;
            tbTelefone2.Text = String.Empty;
            tbTelefone3.Text = String.Empty;
            tbContato.Text = String.Empty;
            tbTelefone4.Text = String.Empty;
            tbTelefone5.Text = String.Empty;
            tbTelefone6.Text = String.Empty;
        }

        void IniciarEdicaoCliente(object sender, TextChangedEventArgs e)
        {
            EditandoCliente(true);
        }
        void FinalizarEdicaoCliente()
        {
            EditandoCliente(false);
        }
        void EditandoCliente(bool editando)
        {
            // Só executa se já tiver terminado de carregar a tela (este método é executado ao inicializar
            // a tela, por causa do preenchimento de alguns controles que inicia a edição do cliente).
            if ( gbAparelhos != null )
            {
                // Armazena valor dizendo se está editando o cliente.
                this.editandoCliente = editando;

                if ( editando )
                {
                    btnPrimeiro.IsEnabled = false;
                    btnAnterior.IsEnabled = false;
                    btnProximo.IsEnabled = false;
                    btnUltimo.IsEnabled = false;
                }
                else
                {
                    VerificarNavegacao();
                }

                btnAdicionar.IsEnabled = !editando;
                btnRemover.IsEnabled = !editando;
                btnSalvar.IsEnabled = editando;
                btnCancelar.IsEnabled = editando;
                btnAtualizar.IsEnabled = !editando;

                tbFiltro.IsEnabled = !editando;
                dgClientes.IsEnabled = !editando;

                gbAparelhos.Visibility = editando ? Visibility.Hidden : Visibility.Visible;
                btnAparelhoRemover.Visibility = editando || dgAparelhos.SelectedItem == null ? Visibility.Hidden : Visibility.Visible;
                btnAparelhoAdicionar.Visibility = editando ? Visibility.Hidden : Visibility.Visible;
            }
        }

        void PreencherEntidadeCliente(Cliente cliente)
        {
            cliente.Nome = tbCliente.Text;
            cliente.Telefone1 = tbTelefone1.Text;
            cliente.Telefone2 = tbTelefone2.Text;
            cliente.Telefone3 = tbTelefone3.Text;
            cliente.Contato = tbContato.Text;
            cliente.Telefone4 = tbTelefone4.Text;
            cliente.Telefone5 = tbTelefone5.Text;
            cliente.Telefone6 = tbTelefone6.Text;
        }

        private void btnAdicionar_Click(object sender, RoutedEventArgs e)
        {
            dgClientes.SelectedItem = null;
            LimparCliente();
            EditandoCliente(true);
        }

        private void btnSalvar_Click(object sender, RoutedEventArgs e)
        {
            int codCliente;
            int.TryParse(lblCodCliente.Content.ToString(), out codCliente);

            if ( this.editandoCliente )
            {
                if ( dgClientes.SelectedItem != null )
                {
                    var cliente = (Cliente)dgClientes.SelectedItem;
                    PreencherEntidadeCliente(cliente);

                    cliente.Salvar();
                }
                else
                {
                    var cliente = new Cliente();
                    PreencherEntidadeCliente(cliente);

                    cliente.Salvar();

                    this.clientes.Add(cliente);
                    this.clientes.Sort((a, b) => a.Nome.CompareTo(b.Nome));

                    ((List<Cliente>)dgClientes.ItemsSource).Add(cliente);
                    dgClientes.Items.Refresh();

                    dgAparelhos.SelectedItem = cliente;
                }
            }

            FinalizarEdicaoCliente();
        }
        private void btnCancelar_Click(object sender, RoutedEventArgs e)
        {
            // Preenche novamente os campos com as informações carregadas do banco de dados.
            PreencherCliente();

            // Volta ao estado normal, sem estar em inclusão ou edição.
            FinalizarEdicaoCliente();
        }

        private void btnRemover_Click(object sender, RoutedEventArgs e)
        {
            if ( dgClientes.SelectedItem != null )
            {
                if ( MessageBox.Show("Deseja realmente remover esse cliente?", "Remoção de cliente", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes )
                {
                    var cliente = (Cliente)dgClientes.SelectedItem;

                    cliente.Remover();

                    clientes.Remove(cliente);

                    ((List<Cliente>)dgClientes.ItemsSource).Remove(cliente);
                    dgClientes.Items.Refresh();

                    LimparCliente();
                }
            }
            else
                MessageBox.Show("Selecione o cliente para ser removido", "Remoção de cliente", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }

        #endregion


        #region Serviço

        void CarregarServicos()
        {
            if ( null == dgClientes.SelectedItem )
                dgAparelhos.ItemsSource = null;
            else
            {
                var selecionado = (Cliente)dgClientes.SelectedItem;
                dgAparelhos.ItemsSource = Servico.Carregar(selecionado.CodCliente.Value);
            }
        }

        private void dgAparelhos_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if ( null != dgAparelhos.SelectedItem )
            {
                var selecionado = (Servico)dgAparelhos.SelectedItem;

                var situacao = (from ComboBoxItem item in cmbSituacao.Items
                                where null != item.Content && item.Content.ToString().ToUpper() == selecionado.Situacao.ToUpper()
                                select item).FirstOrDefault();

                cmbSituacao.SelectedItem = situacao;

                cbPago.IsChecked = selecionado.Pago;
                tbOrcamento.Numero = selecionado.Orcamento.HasValue ? selecionado.Orcamento.Value : 0;
                tbDefeito.Text = selecionado.Defeito;
                tbAcoes.Text = selecionado.Acoes;
                tbObservacoes.Text = selecionado.Observacoes;

                btnAparelhoRemover.Visibility = Visibility.Visible;
            }
            else
            {
                btnAparelhoRemover.Visibility = Visibility.Hidden;
            }
        }

        private void cmbSituacao_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if ( null != dgAparelhos.SelectedItem )
            {
                var selecionado = (Servico)dgAparelhos.SelectedItem;

                dpSituacaoData.IsEnabled = true;

                switch ( cmbSituacao.SelectedIndex )
                {
                    case 1: dpSituacaoData.SelectedDate = selecionado.SituacaoOrcamento; break;
                    case 2: dpSituacaoData.SelectedDate = selecionado.SituacaoCancelado; break;
                    case 3: dpSituacaoData.SelectedDate = selecionado.SituacaoEsperandoPecas; break;
                    case 4: dpSituacaoData.SelectedDate = selecionado.SituacaoAprovado; break;
                    case 5: dpSituacaoData.SelectedDate = selecionado.SituacaoPronto; break;
                    case 6: dpSituacaoData.SelectedDate = selecionado.SituacaoEntregue; break;
                    default:
                        dpSituacaoData.SelectedDate = null;
                        dpSituacaoData.IsEnabled = false;
                        break;
                }
            }
        }


        private void btnPrimeiro_Click(object sender, RoutedEventArgs e)
        {
            dgClientes.SelectedIndex = 0;
        }
        private void btnAnterior_Click(object sender, RoutedEventArgs e)
        {
            dgClientes.SelectedIndex--;
        }
        private void btnProximo_Click(object sender, RoutedEventArgs e)
        {
            dgClientes.SelectedIndex++;
        }
        private void btnUltimo_Click(object sender, RoutedEventArgs e)
        {
            dgClientes.SelectedIndex = dgClientes.Items.Count - 1;
        }

        #endregion

    }
}
